﻿// MyNotes - Free Sticky Notes
// Copyright (C) 2011 Alexandre Vicenzi
// 
// This program is free software; you can redistribute it and/or modify it under 
// the terms of the GNU General Public License as published by the Free Software 
// Foundation; either version 3 of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful, but WITHOUT 
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with 
// this program; if not, write to the Free Software Foundation, Inc., 
// 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Drawing;

namespace MyNotes
{
    class ParseXML
    {
        private XmlDocument doc = new XmlDocument();
        private XmlElement root;
        private static string annotationsPath = "MyNote.Annotations.xml";

        #region XML Annotation
        // Cria a base do arquivo xml.
        public static void CreateXMLAnnotation()
        {
            XmlDocument doc = new XmlDocument();
            XmlNode root = doc.CreateElement("annotations");
            doc.AppendChild(root);
            doc.Save(annotationsPath);
        }

        public static void InsertAnnotation(AnnotationType type, string text, NoteColor color, Point location, Size size, bool locked)
        {
            InsertAnnotation(GetLastNodeID(), type, text, color, location, size, locked);
        }


        private static void InsertAnnotation(int noteID, AnnotationType typeNote, string noteText, NoteColor noteColor, Point location, Size formSize, bool locked)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(annotationsPath);

            XmlNode node = doc.CreateElement("note");

            XmlAttribute id = doc.CreateAttribute("id");
            XmlAttribute locke = doc.CreateAttribute("locked");

            XmlNode text = doc.CreateElement("text");
            XmlNode type = doc.CreateElement("type");
            XmlNode color = doc.CreateElement("color");

            XmlNode loc = doc.CreateElement("location");
            XmlNode x = doc.CreateElement("x");
            XmlNode y = doc.CreateElement("y");
            XmlNode size = doc.CreateElement("size");
            XmlNode width =  doc.CreateElement("width");
            XmlNode height = doc.CreateElement("height");

            id.InnerText = noteID.ToString();
            locke.InnerText = locked.ToString();
            text.InnerText = noteText;
            type.InnerText = typeNote.ToString();
            color.InnerText = noteColor.ToString();

            x.InnerText = location.X.ToString();
            y.InnerText = location.Y.ToString();
            width.InnerText = formSize.Width.ToString();
            height.InnerText = formSize.Height.ToString();

            node.Attributes.Append(id);
            node.Attributes.Append(locke);

            loc.AppendChild(x);
            loc.AppendChild(y);
            size.AppendChild(height);
            size.AppendChild(width);

            node.AppendChild(text);
            node.AppendChild(type);
            node.AppendChild(color);
            node.AppendChild(loc);
            node.AppendChild(size);

            // Adiciona no nó principal.
            doc.SelectSingleNode("/annotations").AppendChild(node);
            // Salva o XML.
            doc.Save(annotationsPath);
        }

        //
        public void UpdateAnnotation(int id)
        {
            XmlDocument doc = new XmlDocument();
            // Carrega o XML.
            doc.Load(annotationsPath);
            // Procura o nó pelo ID.
            XmlNode node = doc.SelectSingleNode(String.Format("/annotations/note[id={0}]", id));
            // Altera o valor.
            node.SelectSingleNode("./text").InnerText = "haha";
            doc.Save(annotationsPath);
        }

        public void RemoveNote(int id)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(annotationsPath);

            foreach (XmlNode node in doc.DocumentElement.ChildNodes)
            {
                // Item(0) = 1o elemento do nó, nesse caso o ID.
                if (int.Parse(node.ChildNodes.Item(0).InnerText) == id)
                {
                    doc.DocumentElement.RemoveChild(node);
                    doc.Save(annotationsPath);
                    return;
                }
            }
        }

        // Retorna o ultimo ID
        private static int GetLastNodeID()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(annotationsPath);
            XmlNodeList nodes = doc.SelectNodes("/annotations/note");

            int lastNote = 0;
            foreach (XmlNode node in nodes)
            {
                int value = int.Parse(node.ChildNodes.Item(0).InnerText);
                if (value > lastNote)
                    lastNote = value;
            }
            lastNote++;
            return lastNote;
        }

        #endregion


        
        #region XML Configurations

        /// <summary>
        /// Create a basic XML for Configurations.
        /// </summary>
        public static void CreateXMLConfig()
        {
            XmlDocument doc = new XmlDocument();
            // Alert for dummies... rsrs
            XmlNode readme = doc.CreateComment("README:\n\tDo not modify this file. This file contains important information for the functioning of the application.\n\tTHANKS XD.");
            XmlElement root = doc.CreateElement("configurations"); // Root node.
            XmlElement defaultConf = doc.CreateElement("annotations"); // Default config note node. 
            XmlElement language = doc.CreateElement("languages"); // Supported languages node.
            XmlAttribute version = doc.CreateAttribute("version"); // Config version.
            version.Value = "1.0"; // Increase only when a new item is added.
            root.Attributes.Append(version);
            root.AppendChild(readme);
            root.AppendChild(defaultConf);
            root.AppendChild(language);
            doc.AppendChild(root);
            // Save.
            doc.Save(Configurations.ConfigFileName);
        }

        #endregion

        #region XML Languages

        public static void CreateLanguageNode(string isoCode, string desc, string revision, string fileName, string authorName)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(Configurations.ConfigFileName);

            XmlNode node = doc.CreateElement("language");

            XmlAttribute ISO639Code = doc.CreateAttribute("ISO639_2Code");
            XmlAttribute version = doc.CreateAttribute("version");
            XmlNode description = doc.CreateElement("description");
            XmlNode file = doc.CreateElement("file");
            XmlNode author = doc.CreateElement("author");

            ISO639Code.InnerText = isoCode;
            description.InnerText = desc;
            version.InnerText = revision;
            file.InnerText = fileName;
            author.InnerText = authorName;

            node.Attributes.Append(ISO639Code);
            node.AppendChild(description);
            node.Attributes.Append(version);
            node.AppendChild(file);
            node.AppendChild(author);

            doc.SelectSingleNode("/configurations/languages").AppendChild(node);
            doc.Save(Configurations.ConfigFileName);
        }

        public static List<string> GetAllLanguages()
        {
            List<string> lng = new List<string>();
            XmlDocument doc = new XmlDocument();
            doc.Load(Configurations.ConfigFileName);

            XmlNodeList nodes = doc.SelectNodes("/configurations/languages/language");

            foreach (XmlNode node in nodes)
            {
                // TODO: Usar selectsinglenode....
                lng.Add(node.ChildNodes[0].InnerText);
            }
            return lng;
        }

        #endregion


        #region XML Translate

        public static string GetTranslatioByTag(string tagId , String file)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(file);
            XmlElement e = doc.GetElementById(tagId);
            return e.InnerText;
        }

        #endregion



        /// <summary>
        /// Load a XML file.
        /// </summary>
        /// <param name="path">Absolute file name for XML.</param>
        /// <returns>Return a XmlDocument</returns>
        public XmlDocument LoadXML(string path)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(path);
            return doc;
        }


        public ParseXML()
        {
        }

        public static void SaveNote()
        {

        }

        public void CreateXMLAnnotation(int a)
        {
            XmlDocument annotationDoc = new XmlDocument();
            XmlElement rootApp = annotationDoc.CreateElement("MyNotes");
            XmlAttribute version = annotationDoc.CreateAttribute("Version");
            version.Value = "1.0";
            rootApp.Attributes.Append(version);
            XmlElement rootNote = annotationDoc.CreateElement("Annotations");
            rootApp.AppendChild(rootNote);
            annotationDoc.AppendChild(rootApp);
            // Salva o xml.
            annotationDoc.Save("annotations.xml");
        }

        public void InsertNewAnnotation(string text)
        {
            XmlDocument xml = new XmlDocument();
            //xml.Load(xmlNoteFileName);


            //xml.AppendChild();

        }

        public XmlElement createAnnotationElement(XmlDocument xmldoc, XmlElement element)
        {
            XmlElement node = xmldoc.CreateElement("");
            node.InnerText = "";
            element.AppendChild(node);
            return node;
        }

        public void CreateRootElement(string name)
        {
            root = doc.CreateElement("MyNotes");
            doc.AppendChild(root);
        }

        public static void SaveUserConfigurations(string fileName)
        {
            try
            {
                XmlDocument doc = new XmlDocument();
                XmlElement config = doc.CreateElement("Configurations");
                XmlAttribute version = doc.CreateAttribute("Version");
                version.Value = "1.0";
                config.Attributes.Append(version);
                XmlElement defaultConf = doc.CreateElement("Default");

                // Cria o nó fonte.
                XmlElement font = CreateTextNode(doc, defaultConf, "Font", "");
                // Cria o sub nó o nome.
                CreateTextNode(doc, font, "Name", Configurations.DefaultFont.Name);
                // Cria o sub nó o tamanho.
                CreateTextNode(doc, font, "Size", Configurations.DefaultFont.Size.ToString());
                // Cria o sub nó o estilo.
                CreateTextNode(doc, font, "Style", Configurations.DefaultFont.Style.ToString());
                // Cria o nó cor padrão.
                CreateTextNode(doc, defaultConf, "DefaultColor", Configurations.DefaultColorNote.ToString());
                // Cria o nó autoStartup.
                CreateTextNode(doc, defaultConf, "StatupWithSystem", Configurations.StartupWithSystem.ToString());
                // Cria o nó showInTasbar.
                CreateTextNode(doc, defaultConf, "ShowInTaskbar", Configurations.ShowInTaskbar.ToString());
                // Cria o nó showCalendar.
                CreateTextNode(doc, defaultConf, "ShowCalendar", Configurations.ShowCalendar.ToString());
                // Cria o nó autoUpdate.
                CreateTextNode(doc, defaultConf, "AutoUpdate", Configurations.AutoUpdate.ToString());
                // Cria o nó idioma.
                CreateTextNode(doc, defaultConf, "Language", Configurations.AppLanguage.ToString());

                config.AppendChild(defaultConf);
                doc.AppendChild(config);
                // Salva o xml.
                doc.Save(fileName);
            }
            catch
            {
                throw;
            }
        }

        // Summary:
        //      Cria um nó no arquivo XML.
        // Parameters:
        //      xmldoc: Documento XML.
        //      element: Elemento do XML onde irá ser adicionado o novo nó.
        //      elementName: Nome do novo nó.
        //      elementInnerText: Texto do novo nó.
        // Returns:
        //      Retorna o nó criado.
        private static XmlElement CreateTextNode(XmlDocument xmldoc, XmlElement element, string elementName, string elementInnerText)
        {
            XmlElement node = xmldoc.CreateElement(elementName);
            node.InnerText = elementInnerText;
            element.AppendChild(node);
            return node;
        }
    }
}
